package com.ruoyi.base.redis.role;

import com.alibaba.fastjson.JSON;
import com.ruoyi.platform.system.menu.pojo.MenuTreeDTO;
import com.ruoyi.platform.system.role.manager.RoleManager;
import com.ruoyi.platform.system.user.dao.role.UserRoleDAO;
import com.ruoyi.platform.system.user.pojo.role.UserRoleDO;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 用户菜单redis
 *
 * @author lcf
 */
@Component
public class UserMenuRedis {

    @Autowired
    public StringRedisTemplate redisTemplate;
    @Autowired
    private UserRoleDAO userRoleRdbDAO;
    @Autowired
    private RoleMenuRedis roleMenuRedis;
    @Autowired
    private RoleManager roleManager;

    /**
     * 网格key
     */
    private final String key = "user_menu";

    /**
     * 缓存时间(h)
     */
    private long cache_time = 1;

    /**
     * 过期时间单位
     */
    private TimeUnit timeUnit = TimeUnit.HOURS;

    /**
     * 删除缓存
     */
    public void delCache(long userId) {
        redisTemplate.delete(getKey(userId));
    }

    /**
     * 缓存用户菜单列表
     */
    public void cache(long userId, List<MenuTreeDTO> list) {
        redisTemplate.boundValueOps(getKey(userId)).set(JSON.toJSONString(list), cache_time, timeUnit);
    }

    /**
     * 获取用户菜单列表
     */
    public List<MenuTreeDTO> getList(long userId) {
        String json = redisTemplate.boundValueOps(getKey(userId)).get();
        if (json != null) {
            return JSON.parseArray(json, MenuTreeDTO.class);
        }

        List<MenuTreeDTO> list = getUserMenuList(userId);
        cache(userId, list);
        return list;
    }

    /**
     * 获取key
     */
    private String getKey(long userId) {
        return key + ":" + userId;
    }

    /**
     * 刷新缓存
     */
    public void refreshIfExist(long userId) {
        Optional.ofNullable(redisTemplate.hasKey(getKey(userId))).ifPresent(x -> {
            if (x) {
                List<MenuTreeDTO> list = getUserMenuList(userId);
                cache(userId, list);
            }
        });
    }

    /**
     * 获取用户菜单权限
     */
    private List<MenuTreeDTO> getUserMenuList(long userId) {
        List<UserRoleDO> userRoleList = userRoleRdbDAO.selectByUserRole(new UserRoleDO(userId));
        if (CollectionUtils.isEmpty(userRoleList)) {
            return roleMenuRedis.getList();
        }

        List<Long> roleIdList = userRoleList.stream().map(UserRoleDO::getRoleId).collect(Collectors.toList());
        return roleManager.getRoleMenuTree(roleIdList);
    }
}
